/*
  The <scheduler.h> header file defines the scheduler constants and functions.
*/

#ifndef _SCHEDULER_H
#define _SCHEDULER_H

#include <types.h>
#include <i386_pmode.h>
#include <linkedlist.h>
#include <a.out.h>

#define NULL_PROCESS_PID      0
#define INIT_PROCESS_PID      1

#define INIT_PROCESS_IDX      0

//#define PROC_STACK_SIZE    4096
#define PROC_STACK_SIZE    8192

/* Process states */
// waiting for admission
#define PS_CREATED            0x000
// executing (current process only, one per CPU)
#define PS_RUNNING            0x001
// being removed (waiting to become dead)
#define PS_TERMINATED         0x002
// ready to be run
#define PS_READY              0x003
// waiting for I/O, semaphores, etc
#define PS_BLOCKED            0x004
// process is being destroyed
#define PS_DEAD               0x005
/* if they're swapped out */
// ready and swapped out
#define PS_READY_SWP          0x083
// blocked and swapped out
#define PS_BLOCKED_SWP        0x084

// Process types
#define TYPE_NORMAL           0x00
#define TYPE_PERIODIC         0x01
// these two are not used for now
#define TYPE_APERIODIC        0x02
#define TYPE_SPORADIC         0x04


// TIME QUANTUM expressed in micro-seconds
//#define TIME_QUANTUM          100
#define TIME_QUANTUM          10000
/* TIME SLICE expressed in number of time quanta */ 
#define TIME_SLICE            10


// User stack top: 
// Kernel - 4 MB - 1 byte (to go to previous page directory entry)
//#define USER_STACK_TOP        0x7FBFFFFF
#define USER_STACK_TOP        0x7FBFFFF0


/* 
   images of executable programs in a.out format 
   a list of these images is created by stuffer
*/

typedef struct {
  byte_t *data;
  dword_t size;
  byte_t name[32];
} image_t;

/* Process memory information */
typedef struct {
  dword_t start;
  int length,pages;
  ptr_list_t addresses;
} memory_section_t;


/* Process memory information */
typedef struct {
  memory_section_t *text,*data,*bss,*heap,*stack;
} process_memory_t;


/* Process structure */

typedef struct {
  // must be first entry, to simplify assembler routine (isr_all_ints)
  dword_t kstack_top; //stacktop of kernel stack
  dword_t ustack_top; //stacktop of user stack

  pid_t   pid;
  /*
  pid_t   parent_pid;
  dword_t owner;
  dword_t group;
  */

  dword_t cr3;
  dword_t state;
  //dword_t time_slice;
  int time_slice;
  dword_t priority;

  // Real-Time information (in milli-seconds)
  // these are filled in by the system call and never changed
  dword_t phase,deadline,period,exec_time;

  // these are filled in by the acceptance test
  dword_t exec_remaining;
  qword_t absolute_deadline;

  //dword_t filehandle;
  /*
  console_t *console;
  memtree_t *vmm_alloc; //memory management info concerning the process 
  //- all its allocated virtual memory
  */
  byte_t name[32];
  byte_t kstack[PROC_STACK_SIZE];  // process' kernel stack

  // pointer to executable image file loaded into memory
  image_t *image_file;
  // pointer to executable header
  struct exec *aout_header;

  // process memory allocations
  process_memory_t *memory_map;

  // allow process to be swapped out
  // set to 0 for system processes
  // set to 1 for user processes
  int swappable;

  // job type
  int type;
  
} process_t;


// Process image list, defined in scheduler.c
// initialized by stuffer
extern volatile ptr_list_t process_image_list;

// Pointer to current process
extern volatile process_t *current_process;

extern void initialize_scheduler(void);
extern void schedule(void);
extern process_t *create_process(image_t *exec_image);
extern void destroy_process(process_t *proc);
extern int aout_loader(process_t *proc,dword_t address);
extern image_t *find_image(char *name);
extern int release_periodic(qword_t current_time);
extern int acceptancy_test(process_t *p);

#endif /* _SCHEDULER_H */
